# !/usr/bin/env python
# -*- coding:utf-8 -*-
# ref_blog:http://www.open-open.com/home/space-5679-do-blog-id-3247.html
import queue
import threading
import time

class WorkManager(object):
    '''
    * 线程和队列管理
    * 可以增加不同参数，执行不同的函数或参数任务
    '''

    def __init__(self, work_num=1000, thread_num=2, args=(), dict={}):
        self.args = args
        self.dict = dict
        # self.kwargs = kwargs
        # print( self.args[0] )
        # print( *self.args[0] )
        # print( self.dict )
        # time.sleep(2)
        self.work_queue = queue.Queue()
        self.threads = []
        self.__init_work_queue(work_num)    # 先初始化队列
        self.__init_thread_pool(thread_num) # 后追加线程


    def __init_thread_pool(self, thread_num):
        """
        初始化线程
        这里是一个线程去监听的函数，监听队列事件
        队列参数的 func arg 真正执行
        """       
        for i in range(thread_num):
            self.threads.append( Work(self.work_queue) )   # 这里是一个线程去监听的函数，监听队列事件

    def __init_work_queue(self, jobs_num):
        """
        初始化工作队列
        """       
        for value in self.dict.values() :  # 可以传入字典对字段进行遍历
            self.add_job( self.args[0] , value )  #队列内部工作任务
            # self.add_job(do_job, i)  #队列内部工作任务

    def add_job(self, func, *args):
        """
        添加一项工作入队
        """        
        self.work_queue.put( ( func,  list(args) ) )  # 任务入队，Queue内部实现了同步机制。put的参数 tuple型
        # self.work_queue.put( (func, list(args)) )  # 任务入队，Queue内部实现了同步机制。put的参数 tuple型

    def check_queue(self):
        """
        检查剩余队列任务
        """
        return self.work_queue.qsize()

    def wait_allcomplete(self):
        """
        等待所有线程运行完毕
        """       
        for item in self.threads:
            if item.is_alive():
                item.join()


class Work( threading.Thread ):
    '''
    * 线程去监听队列中的事件
    通过监听到的去执行事件，
    事件执行后通知系统 self.work_queue.task_done()
    '''

    def __init__(self, work_queue):  # 参数为队列
        threading.Thread.__init__(self)
        self.work_queue = work_queue
        self.start()

    def run(self):
        # 死循环，从而让创建的线程在一定条件下关闭退出
        while True:
            try:
                do, args = self.work_queue.get(
                    block=False)  # 任务异步出队，Queue内部实现了同步机制
                do(args)
                self.work_queue.task_done()  # 通知系统任务完成
            except Exception as e:
                print ( str(e) )
                break
# 具体要做的任务


def do_job(args):
    print (args)
    # time.sleep(0.2)  # 模拟处理时间
    print ("%s --   ",  threading.current_thread() )
    print ("  --  %s",    list(args))

if __name__ == '__main__':
    start = time.time()
    dict1 ={
            "1": "1;COM1;9600;8;N;1;0103000000044409;0",
            "2": "0;COM1;9600;8;N;1;0103000000044409;0"
        }
    work_manager = WorkManager( 2,  2, args=( do_job, [1,2], ),  dict=dict1 ) # 建立2个队列 10个线程
    work_manager.wait_allcomplete()    # 等待任务完成
    end = time.time()
    print ("cost all time: "     )
    print (   end-start )